/**
 * 创建一个表格 - 通过传入数据的方式
*/


// 表格列配置
export interface CreatTableHtmlElement_columnsConf {
  key: string,
  name: string,
  width?: string | number,
  align?: string
}

// 每个单元表格 - 插槽配置 CreatTableHtmlElement_concatSlot.slotInner 
interface CreatTableHtmlElement_slotInnerInter {
  HTMLtext: string;
  mode: CreatTableHtmlElement_InnterSlotModeEnum;
}

// 全插槽配置
export interface CreatTableHtmlElement_concatSlot {
  slotBefore?: string;                    // 插入总结构的头始
  slotAfter?: string;                     // 插入总结构内的末尾
  slotStamp?: string;                     // 插入公章
  slotInner?: [] | CreatTableHtmlElement_slotInnerInter[];      // 插入 table-item 内的具体位置
}

// 组件配置项
export interface CreatTableHtmlElement_options {
  pageLimit?: number;                 // 是否需要区别表格 - 数据总长度超出单页时将创建多个表格(便于打印)
  cssUnit?: 'px' | 'pt' | 'cm';       // 尺寸单位，影响内部style配置及column.width

  pagerPhysicsWidth?: string;         // 纸张横向尺寸
  tableHeight?: string;               // 是否限制 - 单个表格容器高度

  tablePaddingTop?: string;           // 表格单元内边距 padding-top
  tablePaddingBottom?: string;        // 表格单元内边距 padding-bottom
  tableSpace?: string;                // 表格单元 margin-top
  tableBorderColor?: string;          // 表格边框色
  tableBorderWidth?: string;          // 表格边框线宽
  tableZebraColor?: string;           // 表头thead - 背景色
  tableTHPadding?: string;            // 表头thead - 内边距 padding
  tableTDPadding?: string;            // 表格td 内边距 padding
  tableFontSize?: string;             // 表格th、td - 字体大小

  valueBoxHeight?: string;            // 高度
  valueBoxMaxHeight?: string;         // 最大高度
  valueBoxLineHeight?: string;        // 行高  h 1/2
  valueBoxLineClamp?: string;         // 最大显示行数
}

// 每个单元表格 - 插槽类型
export enum CreatTableHtmlElement_InnterSlotModeEnum {    // 插入模式 - 可能插入多个或单个于  table-item DIV 中
  ONLY_FIRST_BEFORE = 'ONLY_FIRST_BEFORE', // 仅首个 - 表格之前插入
  ONLY_FIRST_AFTER = 'ONLY_FIRST_AFTER',   // 仅首个 - 表格之后插入
  ONLY_LAST_BEFORE = 'ONLY_LAST_BEFORE',   // 仅末尾 - 表格之前插入
  ONLY_LAST_AFTER = 'ONLY_LAST_AFTER',     // 仅末尾 - 表格之后插入
  EVERY_BEFORE = 'EVERY_BEFORE',           // 每个之前
  EVERY_AFTER = 'EVERY_AFTER',             // 每个之后
  UNDO = 'UNDO',                           // 无动作
};

const CreatTableHtmlElement = function (columns: CreatTableHtmlElement_columnsConf[] , data: any[], options: CreatTableHtmlElement_options = {}) {

  if (!Array.isArray(columns)) throw Error('columns typeof must Array.');
  if (!Array.isArray(data)) throw Error('data typeof must Array.');

  let defOpts = {           // 默认配置项
    pageLimit: 9999,        // 是否需要区别表格 - 数据总长度超出单页时将创建多个表格(便于打印)
    cssUnit: 'px',          // 单位 px/ pt/ cm...

    pagerPhysicsWidth: '1000px',    // 纸张横向尺寸
    tableHeight: 'auto',            // 是否限制 - 单个表格容器高度
    tablePaddingTop: '0',           // 内部padding-top
    tablePaddingBottom: '0',        // 内部padding-bottom
    tableSpace: '20px',
    tableBorderColor: '#666',
    tableBorderWidth: '1px',
    tableZebraColor: '#eee',
    tableTHPadding: '10px',
    tableTDPadding: '4px 10px',
    tableFontSize: '12px',

    valueBoxHeight: '14px',         // 高度
    valueBoxMaxHeight: '28px',      // 最大高度
    valueBoxLineHeight: '14px',     // 行高  h 1/2
    valueBoxLineClamp: '2',         // 最大显示行数
    ...options
  };

  let colkeys = columns.map(({ key }) => key);     // 获取key序列
  // is DOM
  let DOMcolgroup = ``;   // 表头尺寸控制
  let DOMhead = ``;       // 表头
  let DOMtbody = ``;      // 表主体

  // 获取表格渲染数据 - maybe数据切割
  function splitCutDatas (setDatas: any[]): Array<any[]> | any[] {
    let { pageLimit } = defOpts;
    let Arrs: any[] = [];                               // 装载数组分组后的数据
    let totalLen = setDatas.length;                     // 数据总长度

    if (totalLen > pageLimit) {                         // 需要进行分组
      let pageLen = Math.ceil(totalLen / pageLimit);    // 最大页数
      // 空间预占
      for (let i = 0; i < pageLen; i++) {               // 制造分组格式
        Arrs.push([]);
      }

      setDatas.forEach((item, index) => {
        let limitIdx = Math.floor(index / pageLimit);
        /* let h = (index + limitIdx);
        let m = h % pageLimit; */
        Arrs[limitIdx].push(item);
      });
    } else {
      Arrs = [ ...setDatas ];
    }
    return Arrs;
  }


  /**
  * 获取最终渲染
  * @param slot = { slotBefore 插入之前HTMLstring, slotAfter 插入之后HTMLstring, slotStamp 公章插槽 }
  */
  function getAllTabsHTMLtexts(slot: CreatTableHtmlElement_concatSlot = {}) {

    const { slotBefore = '', slotAfter = '', slotStamp = '', slotInner = [] } = slot;

    let renderListdata = splitCutDatas(data);   // [[...], [...], ...]  ||  [...]
    let allHtmlText = '';

    resetValues();                // 置空变量
    getTableCommonHTMLtexts();    // 完成<thead> + <colgroup>构造

    let htmlGroupSlots: { [x: string]: string} = {};            // 集合插槽

    if (slotInner.length > 0) {         // 制作 HTMLtext 结构分类
      slotInner.forEach(({ HTMLtext, mode }) => {
        if (Object.keys(CreatTableHtmlElement_InnterSlotModeEnum).includes(mode)) {
          htmlGroupSlots[mode] = HTMLtext;
        }
      });
    }

    let setSlots = { ...htmlGroupSlots, slotStamp };    // 插槽对象

    // 二维数组 - [[...], ...]
    if (renderListdata.length && Array.isArray(renderListdata[0])) {

      // 针对slot类型进行排除不符合条件的
      renderListdata.forEach((itemArray, index) => {
        let slotCopy = JSON.parse(JSON.stringify(setSlots));

        if (index > 0) {                                        // index is first
          slotCopy[CreatTableHtmlElement_InnterSlotModeEnum.ONLY_FIRST_BEFORE] && delete slotCopy[CreatTableHtmlElement_InnterSlotModeEnum.ONLY_FIRST_BEFORE];
          slotCopy[CreatTableHtmlElement_InnterSlotModeEnum.ONLY_FIRST_AFTER] && delete slotCopy[CreatTableHtmlElement_InnterSlotModeEnum.ONLY_FIRST_AFTER];
        } else if (renderListdata.length -1 === index ) {       // index is last
          slotCopy[CreatTableHtmlElement_InnterSlotModeEnum.ONLY_LAST_BEFORE] && delete slotCopy[CreatTableHtmlElement_InnterSlotModeEnum.ONLY_LAST_BEFORE];
          slotCopy[CreatTableHtmlElement_InnterSlotModeEnum.ONLY_LAST_AFTER] && delete slotCopy[CreatTableHtmlElement_InnterSlotModeEnum.ONLY_LAST_AFTER];
        }

        allHtmlText += getTableHTMLtexts(itemArray, slotCopy);
      });
    }
    // 平层数组 - [...]
    else {
      allHtmlText = getTableHTMLtexts(data, setSlots);
    }

    return `<div class="table-all-wrap">
      ${slotBefore}
      ${allHtmlText}
      ${slotAfter}
      ${tableStyle()}
    </div>`
  }

  // 获取表格通用表头结构 - <thead> + <colgroup>
  function getTableCommonHTMLtexts() {
    columns.forEach((item, index: number) => {
      let { key, name, width, ...other } = item;
      DOMhead += CreatDOM_theadTH(name);
      DOMcolgroup += CreatDOM_colgroupItem(width);
    });

    DOMhead = `<tr>${DOMhead}</tr>`;
    DOMcolgroup = `<colgroup>${DOMcolgroup}</colgroup>`;

    return {
      DOMhead,
      DOMcolgroup
    }
  }

  /**
   * 生成完整的表格 - 单个表格
   * @param _datas  当前页面（分页/单页）数据
   * @param arg[1]  单元表格内容的插槽集合
   */
  function getTableHTMLtexts (
    _datas: any[],
    {
      slotStamp,
      ONLY_FIRST_BEFORE = '', ONLY_FIRST_AFTER = '', ONLY_LAST_BEFORE = '', ONLY_LAST_AFTER = '',
      EVERY_BEFORE = '', EVERY_AFTER = ''
    }: { [x: string]: string }
  ) {
    DOMtbody = `<tbody>${ CreatDOM_tbody(_datas) }</tbody>`;

    return `<div class="table-item">
      ${ONLY_FIRST_BEFORE}
      ${ONLY_LAST_BEFORE}
      ${EVERY_BEFORE}
      <table>
        ${DOMhead}
        ${DOMcolgroup}
        ${DOMtbody}
      </table>
      ${ONLY_FIRST_AFTER}
      ${ONLY_LAST_AFTER}
      ${EVERY_AFTER}
      ${slotStamp}
    </div>`;
  }

  // 重置相关数值
  function resetValues () {
    DOMcolgroup = ``;   // 表头尺寸控制
    DOMhead = ``;       // 表头
    DOMtbody = ``;
  }

  /**
   * 创建表格尺寸控制
   * @param width [ number | false ]
  */
  function CreatDOM_colgroupItem (width: number | string | undefined) {
    let intWidth = Number(parseFloat(width as string));
    let filWidth = (width && Boolean(intWidth)) ? intWidth : false;

    return filWidth ?
      `<col style="width: ${cssUnitSetup(filWidth)};">`
      :
      `<col>`
    ;
  }

  // 创建表头
  function CreatDOM_theadTH (key: string) {
    return `<th>${key}</th>`;
  }

  /**
  *   创建表主体
  *   @param itemConf = { key, name, width, align }
  */
  function CreatDOM_tbody (data: any[]) {
    let TRsdom = '';
    data.forEach((row, line) => {

      let TDsdom = colkeys.map((key, columIndex) => {
        let { align } = columns[columIndex];

        let setValue = row[key] !== undefined && row[key] !== null ? row[key] : '-';
        let cssAlign = typeof align === 'string' && ['center', 'left', 'right'].includes(align) ? `text-align:${align};`: '';
        return `<td style="${cssAlign}"><div class="td-valueBox">${setValue}</div></td>`;
      });

      TRsdom += `<tr>${ TDsdom.join('') }</tr>`;
    });

    return TRsdom;
  }

  function tableStyle () {

    let {
      pagerPhysicsWidth,
      tableHeight, tablePaddingTop, tablePaddingBottom, tableSpace, tableBorderColor, tableBorderWidth, tableZebraColor, tableTHPadding, tableTDPadding, tableFontSize,
      valueBoxHeight, valueBoxMaxHeight, valueBoxLineHeight, valueBoxLineClamp,
    } = defOpts;
    return `
    <style>
      .table-all-wrap {
        width: ${pagerPhysicsWidth};
      }

      .table-all-wrap .table-item {
        position: relative;
        margin-bottom: ${tableSpace};
        padding-top: ${tablePaddingTop};
        padding-bottom: ${tablePaddingBottom};
        height: ${tableHeight};
        box-sizing: border-box;
      }

      .table-all-wrap .td-valueBox {
        width: 100%;
        /* height: ${valueBoxHeight}; min-height: ${valueBoxHeight};*/
        
        max-height: ${valueBoxMaxHeight};
        line-height: ${valueBoxLineHeight};
        display: -webkit-box;
        text-overflow: ellipsis;
        -webkit-line-clamp: ${valueBoxLineClamp};
        -webkit-box-orient: vertical;
        overflow: hidden;
      }

      .table-all-wrap table {
        border: ${tableBorderWidth} solid ${tableBorderColor};
        border-collapse: collapse;
      }

      .table-all-wrap table th,
      .table-all-wrap table td {
        font-size: ${tableFontSize};
        border-right: ${tableBorderWidth} solid ${tableBorderColor};
        border-bottom: ${tableBorderWidth} solid ${tableBorderColor};
      }

      .table-all-wrap table th {
        padding: ${tableTHPadding};
        background-color: ${tableZebraColor};
      }

      .table-all-wrap table td {
        padding: ${tableTDPadding};
      }

      .table-all-wrap table th:nth-last-child(1),
      .table-all-wrap table td:nth-last-child(1) {
        border-right: none;
      }

      .table-all-wrap table tr:nth-of-type(even) {
        background-color: ${tableZebraColor};
      }
    </style>`;
  }

  // number 赋值单位
  function cssUnitSetup(number: number) {
    return `${number}${defOpts.cssUnit}`;
  }

  return getAllTabsHTMLtexts;
}

export default CreatTableHtmlElement;
  
  